/**************************************************************************//**
 * @item     CosyOS Kernel
 * @file     sv_task.h
 * @brief    任务服务（仅在任务中调用）
 * @author   迟凯峰
 * @version  V3.3.4
 * @date     2023.09.12
 ******************************************************************************/

#ifndef __SV_TASK_H
#define __SV_TASK_H

extern tECODE __start_task(tspTaskHandle task_hand, u8 state);
extern tECODE __resume_task (tspTaskNode task_node);
extern tECODE __suspend_task(tspTaskNode task_node);
extern tECODE __delete_task (tspTaskNode task_node);
extern tECODE __ressus_task (tspTaskNode task_node);
extern tECODE __set_priority(tspTaskNode task_node, u8 tpl);

extern void __delay(tDelay tc);
extern bool __set_delay(tspTaskNode task_node, tDelay tc);
extern bool __clr_delay(tspTaskNode task_node);

extern tECODE __free_mut(tspMut p);
extern bool __take_mut(tspMut p, tDelay tc);
extern bool __wait_bin(bool _XDATA_MEM_ *p, tDelay tc);
extern bool __take_bin(bool _XDATA_MEM_ *p, tDelay tc);
extern bool __take_sem(tSemSize _XDATA_MEM_ *c, tDelay tc);
extern void __free_sem(tspSem p);

extern tFetion __recv_fetion(tFetion _XDATA_MEM_ *tbox, tDelay tc);
extern bool __recv_dm   (tDM  _XDATA_MEM_ *nf, tDelay tc);
extern bool __recv_mail (bool _XDATA_MEM_ *gf, tDelay tc);
extern void __send_mail (void _XDATA_MEM_ *gm, void *lm, size_t size, bool _XDATA_MEM_ *gf);
extern void  *__recv_msg(tspMsgQueue msg_queue, tDelay tc);
extern tECODE __send_msg(tspMsgQueue msg_queue, void *msg);
extern bool __query_grp (void _XDATA_MEM_ *p, u8 size);
extern bool __wait_grp  (void _XDATA_MEM_ *p, u8 size, tDelay tc);
extern void __write_gvar(void *gp, void *lp, size_t size);
extern void __sope_gvar (void *gp, void *lp, tfpVV fp);

extern void _MALLOC_MEM_ *__uxalloc      (void _MALLOC_MEM_ *p);
extern bool               __uinit_mempool(tspThrmem p, size_t size);
extern void _MALLOC_MEM_ *__utalloc      (tspThrmem p, size_t size);



/*
 * 任务
 */

/* 启动任务 */
#define sUSV_StartTask(thdl, state) \
( \
	__enter_critical_ret() || true ? __start_task(thdl, !state ? __READY__ : __READY__ | __SUSPENDED__) : false \
)

/* 恢复任务 */
#define	sUSV_ResumeTask(node) \
( \
	__enter_critical_ret() || true ? __resume_task(node) : false \
)

/* 挂起任务 */
#define	sUSV_SuspendTask(node) \
( \
	__enter_critical_ret() || true ? __suspend_task(node) : false \
)

/* 删除任务 */
#define	sUSV_DeleteTask(node) \
( \
	__enter_critical_ret() || true ? __delete_task(node) : false \
)

/* 恢复指定任务并挂起自身任务 */
#define	sUSV_ResSusTask(node) \
( \
	__enter_critical_ret() || true ? __ressus_task(node) : false \
)

/* 设置任务优先级 */
#define	sUSV_SetPriority(node, tpl) \
( \
	__enter_critical_ret() || true ? __set_priority(node, tpl) : false \
)



/*
 * 延时
 */

/* 自身任务延时 */
#define	sUSV_Delay(tc) \
do{ \
	mEnterCritical; \
	__delay(tc); \
}while(false)

/* 设置延时 */
#define sUSV_SetDelay(node, tc) \
( \
	__enter_critical_ret() || true ? __set_delay(node, tc) : false \
)

/* 清除延时 */
#define sUSV_ClearDelay(node) \
( \
	__enter_critical_ret() || true ? __clr_delay(node) : false \
)



/*
 * 定时
 */

/* 定时中断 */
#define	sUSV_TimInt(tmid, tc) \
do{ \
	mEnterCritical; \
	vTIMINT_STMR[tmid] = vTIMINT_BUFF[tmid] = tc; \
	mExitCritical; \
}while(false)

/* 定时查询 */
#define	sUSV_TimQry(tmid, tc) \
do{ \
	mEnterCritical; \
	vTIMQRY_STMR[tmid] = vTIMQRY_BUFF[tmid] = tc; \
	mExitCritical; \
}while(false)



/*
 * 互斥信号量
 */

/* 释放 */
#define sUSV_FreeMut(mut) \
( \
	__enter_critical_ret() || true ? __free_mut(&mut) : false \
)

/* 获取 */
#define	sUSV_TakeMut(mut, tc) \
( \
	__enter_critical_ret() || true ? __take_mut(&mut, tc) : false \
)



/*
 * 二值信号量
 */

/* 等待 */
#define	sUSV_WaitBin(bin, tc) \
( \
	__enter_critical_ret() || true ? __wait_bin((bool *)&bin, tc) : false \
)

/* 获取 */
#define	sUSV_TakeBin(bin, tc) \
( \
	__enter_critical_ret() || true ? __take_bin((bool *)&bin, tc) : false \
)



/*
 * 计数信号量
 */

/* 获取 */
#define sUSV_TakeSem(sem, tc) \
( \
	__enter_critical_ret() || true ? __take_sem((tSemSize *)&sem.counter, tc) : false \
)

/* 释放 */
#define sUSV_FreeSem(sem) \
do{ \
	mEnterCritical; \
	__free_sem(&sem); \
}while(false)



/*
 * 飞信
 */

/* 接收飞信 */
#define sUSV_RecvFetion(tbox, tc) \
( \
	__enter_critical_ret() || true ? __recv_fetion((tFetion *)&tbox, tc) : false \
)



/*
 * 私信
 */

/* 接收私信 */
#define	sUSV_RecvDM(tc) \
( \
	__enter_critical_ret() || true \
	? __recv_dm(&m0_, tc) \
		? __memcpy(&m0 + 1, &m0_ + 1, __DM_SIZE__) || true \
			? __exit_critical_ret() \
			: __exit_critical_ret() \
		: false \
	: false \
)

/* 发送私信 */
#if SYSCFG_COMPILEMODE == __C89__
	#define	sUSV_SendDM(task) \
		mEnterCritical; \
		vSendDM_f = true; \
		__DM_PSP__; \
		while(true) \
		if(!vSendDM_f) \
		{ \
			mExitCritical; \
			break; \
		} \
		else task(__DM_VAL__, 
#elif SYSCFG_COMPILEMODE == __C99__
	#define sUSV_SendDM(task, ...) \
	do{ \
		mEnterCritical; \
		vSendDM_f = true; \
		__DM_PSP__; \
		task(__DM_VAL__, __VA_ARGS__); \
		mExitCritical; \
	}while(false)
#endif



/*
 * 消息邮箱
 */

/* 接收邮件 */
#define sUSV_RecvMail(mail, mbox, tc) \
( \
	__enter_critical_ret() || true \
	? __recv_mail((bool *)&mbox##_gnmf, tc) \
		? __memcpy(mail, &mbox, sizeof(mbox)) || true \
			? __exit_critical_ret() \
			: __exit_critical_ret() \
		: false \
	: false \
)

/* 发送邮件 */
#define sUSV_SendMail(mbox, mail) \
do{ \
	mEnterCritical; \
	__send_mail(&mbox, mail, sizeof(mbox), (bool *)&mbox##_gnmf); \
}while(false)



/*
 * 消息队列
 */

/* 发送消息 */
#define	sUSV_SendMsg(que, msg) \
( \
	__enter_critical_ret() || true ? __send_msg(que, msg) : false \
)

/* 接收消息 */
#define	sUSV_RecvMsg(que, tc) \
( \
	__enter_critical_ret() || true ? __recv_msg(que, tc) : NULL \
)



/*
 * 事件标志组
 */

/* 查询标志组 */
#define	sUSV_QueryFlagGroup(group) \
( \
	__enter_critical_ret() || true ? __query_grp((void *)&group, sizeof(group)) : false \
)

/* 等待标志组 */
#define	sUSV_WaitFlagGroup(group, tc) \
( \
	__enter_critical_ret() || true ? __wait_grp((void *)&group, sizeof(group), tc) : false \
)

/* 清除标志组 */
#define sUSV_ClearFlagGroup(group) \
do{ \
	mEnterCritical; \
	sizeof(group) == 1 ? *(u8  *)&group = false : OS_NOPx1; \
	sizeof(group) == 2 ? *(u16 *)&group = false : OS_NOPx1; \
	sizeof(group) == 4 ? *(u32 *)&group = false : OS_NOPx1; \
	mExitCritical; \
}while(false)

/* 写标志位 */
#define sUSV_WriteFlagBit(group, bit, value) \
do{ \
	mEnterCritical; \
	group.bit = value; \
	mExitCritical; \
}while(false)



/*
 * 全局变量
 */

/* 读全局变量 */
#define sUSV_ReadGVar(gv) \
( \
	__enter_critical_ret() || true ? gv : gv \
); \
mExitCritical

/* 读全局数组 */
#define sUSV_ReadGAry(lp, gp, size) \
do{ \
	mEnterCritical; \
	__memcpy(lp, gp, size); \
	mExitCritical; \
}while(false)

/* 读全局字符串 */
#define sUSV_ReadGStr(ls, gs) \
do{ \
	mEnterCritical; \
	__strcpy(ls, gs); \
	mExitCritical; \
}while(false)

/* 全局变量写访问 */
#define sUSV_WriteGVar(gp, lp, size) \
do{ \
	mEnterCritical; \
	__write_gvar(gp, lp, size); \
}while(false)

/* 全局变量自运算 */
#define sUSV_SelfOpe(gv, type, fp) \
do{ \
	static type lv; \
	mEnterCritical; \
	lv = gv; \
	__sope_gvar(&gv, &lv, fp); \
}while(false)



/*
 * 进程内存
 */

/* malloc */
#define	sUSV_Malloc(size) \
( \
	__enter_critical_ret() || true ? __uxalloc(__malloc(size)) : NULL \
)

/* calloc */
#define	sUSV_Calloc(nmemb, size) \
( \
	__enter_critical_ret() || true ? __uxalloc(__calloc(nmemb, size)) : NULL \
)

/* realloc */
#define	sUSV_Realloc(p, size) \
( \
	__enter_critical_ret() || true ? __uxalloc(__realloc(p, size)) : NULL \
)

/* free */
#define	sUSV_Free(p) \
do{ \
	mEnterCritical; \
	__free(p); \
	mExitCritical; \
}while(false)



/*
 * 线程内存
 */

/* 初始化线程内存池 */
#define	sUSV_InitMempool(size) \
( \
	__enter_critical_ret() || true ? __uinit_mempool(&thrmem, size) : false \
)

/* 线程内存分配 */
#define	sUSV_Talloc(size) \
( \
	__enter_critical_ret() || true ? __uxalloc(__talloc(&thrmem, size)) : NULL \
)

/* 释放线程内存池 */
#define	sUSV_FreeMempool \
do{ \
	sUSV_Free(thrmem.p1); \
	thrmem.p1 = thrmem.p2 = NULL; \
}while(false)



#endif
